/*
 * topological-hex, a program to compute combinatorial hexahedral meshes.
 *
 * Copyright (C) <2018> <Université catholique de Louvain (UCL), Belgique>
 *
 * List of the contributors to the development, description and complete
 * License: see LICENSE file.
 *
 * This program (topological-hex) is free software:
 * you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see COPYING file).  If not,
 * see <http://www.gnu.org/licenses/>.
 */

#ifndef SERVER_H_
#define SERVER_H_

#include "solver.h"
#include <stdatomic.h>
#include <stdbool.h>

#include "parallel_dfs.h"
#include "protocol.h"

/**
 * @defgroup distributed
 *
 * Enumerating all hex meshes is a demanding task. This module allows a
 * distributed system to be used to perform it more quickly.
 *
 * A server can be started with @ref server_run. Clients can then start
 * connecting to it using @ref server_run_distributed and @ref
 * server_run_distributed_clietn.
 *
 * @see distributed-protocol
 */

/**
 * @addtogroup distributed
 * @{
 */

/**
 * Information about the directory in which the server will store its progress,
 * allowing execution to be resumed after an interruption.
 */
typedef struct server_backup_info {
  /**
   * Path to the directory in which backups will be stored.
   */
  const char *directory;

  /**
   * If true, restore the state of the program for a directory.
   */
  bool try_restore;
} server_backup_info;

/**
 * Function called on the server when a solution is found.
 *
 * @param user_name Name of the user who found the solution
 * @param vertices Contents of the solution
 * @param num_hexes Number of hexahedra in the solution
 * @param data Pointer to user data, as passed to @ref server_run
 */
typedef void (*server_callback)(
  const char *user_name,
  const vertex_index *vertices, hex_index num_hexes, void *data);

/**
 * Function called when the server needs to log an event.
 *
 * @param message C-string containing the message
 * @param data Pointer to user data, as passed to @ref server_run
 */
typedef void (*server_log)(
  const char *message, void *data);

/**
 * Function called when the server starts listening for connections.
 */
typedef void (*server_listen_cb)(void *data);

/**
 * Function called when problems have successfully been explored.
 *
 * @param i Number of finished subproblems
 * @param n Total number of subproblems
 * @param data Pointer to user data, as passed to @ref server_run
 */
typedef void (*server_progress_cb)(uint32_t i, uint32_t n, void *data);

/**
 * Runs a server to find hex-meshes on a distributed system.
 *
 * @param cb Function to call when a solution is found
 * @param user_data Argument to pass to @p cb
 * @param log Function to call when logging messages
 * @param log_data Argument to pass to @p log
 * @param listen_cb Function to call when the server starts listening for
 *   connections.
 * @param listen_data Argument to pass to @p listen_cb.
 * @param progress_cb Function to call when progress is made on the subproblem.
 * @param progress_data Argument to pass to @p progress_cb.
 * @param backup_info Directory used to store backups, or NULL if none should be
 *   used.
 */
error_code server_run(server_callback cb, void *user_data,
                      server_log log, void *log_data,
                      server_listen_cb listen_cb, void *listen_data,
                      server_progress_cb progress, void *progress_data,
                      server_backup_info *backup);

/**
 * @}
 */

#endif
